package TokenRecognizer;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author jefoutta
 */
import java.util.*;

public class InfixToPrefix {

    public String getPrefix(String infix){
        String temp = this.infixToPrefixText(this.addConcat(infix));
        return temp;
    }

    private String addConcat(String infix){
        String temp = "";
        String alphabet = "abcdefghijklmnopqrstuvwxyz";
        for(int i = 0; i < infix.length(); i++){
            Character actChar = infix.charAt(i);
            if(i > 0){
                Character lastChar = temp.charAt(temp.length() - 1);
                if(alphabet.contains(lastChar.toString()) || lastChar == ')' || lastChar == '*')
                    if(alphabet.contains(actChar.toString()) || actChar == '(')
                        temp = temp + ".";
            }
            temp = temp + actChar;
        }
        return temp;
    }

    private String infixToPrefixText(String infix){
        Stack<Character> stack1 = infixToPrefix(infix);
        String text = "";
        while (stack1.size() > 0)
            text += stack1.pop();
        return text;
    }

    private Stack<Character> infixToPrefix(String infix){
        infix = '(' + infix;
        Integer size = infix.length();
        Stack<Character> finalStack = new Stack();
        Stack<Character> tempStack = new Stack();
        tempStack.push(')');
        for (int i = size - 1; i > -1; i--){
            Character c = infix.charAt(i);
            switch (c){
                case ')':
                    tempStack.push(c);
                break;
                case '.':
                case '*':
                case '|':
                    while (priority(c) > priority(tempStack.peek()))
                        finalStack.push(tempStack.pop());
                    tempStack.push(c);
                    break;
                case '(':
                    while (tempStack.peek() != ')')
                        finalStack.push(tempStack.pop());
                    tempStack.pop();
                    break;
                default:
                    finalStack.push(c);
                    break;
            }
        }
        return finalStack;
    }

    private Integer priority(Character c){
        Integer res = 0;
        switch (c){
            case ')':res = 4;break;
            case '|':res = 3;break;
            case '.':
            case '*':res = 2;break;
            case '(':res = 1;break;
        }
        return res;
    }
}
